#include <stdio.h>

// Abstract Products
typedef struct {
    void (*read)(void);
} Sensor;

// Concrete Products
typedef struct {
    Sensor base;
} DS18B20Sensor;

void readDS18B20(void) {
    printf("Reading from DS18B20 temperature sensor.\n");
}

DS18B20Sensor* createDS18B20Sensor() {
    static DS18B20Sensor sensor = { readDS18B20 };
    return &sensor;
}

typedef struct {
    Sensor base;
} DHT22Sensor;

void readDHT22(void) {
    printf("Reading from DHT22 humidity sensor.\n");
}

DHT22Sensor* createDHT22Sensor() {
    static DHT22Sensor sensor = { readDHT22 };
    return &sensor;
}

// Abstract Factory
typedef struct {
    Sensor* (*createTemperatureSensor)(void);
    Sensor* (*createHumiditySensor)(void);
} SensorFactory;

// Concrete Factory
typedef struct {
    SensorFactory base;
} ConcreteSensorFactory;

Sensor* createTemperatureSensorInFactory(void) {
    return (Sensor*) createDS18B20Sensor();
}

Sensor* createHumiditySensorInFactory(void) {
    return (Sensor*) createDHT22Sensor();
}

ConcreteSensorFactory* createConcreteSensorFactory() {
    static ConcreteSensorFactory factory = {
        createTemperatureSensorInFactory,
        createHumiditySensorInFactory
    };
    return &factory;
}

// Client code
void useSensors(SensorFactory* factory) {
    Sensor* tempSensor = factory->createTemperatureSensor();
    Sensor* humiditySensor = factory->createHumiditySensor();
    
    tempSensor->read();
    humiditySensor->read();
}

int main() {
    SensorFactory* factory = (SensorFactory*) createConcreteSensorFactory();
    useSensors(factory);
    return 0;
}
